/*
 * Created on 03.apr.2006
 * Created by Tomas
 */
package placing;
import java.util.Iterator;
import java.util.List;

import org.junit.*;

import people.Group;
import people.Person;
import people.PersonNotFoundException;

import junit.framework.TestCase;

public class PlaceTest extends TestCase {
	Place upOne, upTwo, downOne, downTwo;
	Room upstairs, downstairs, cellar;
	Person bob, pat, nev, bub;
	Group fun;


	@Before
	protected void setUp() throws Exception {
		upstairs 	= new Room(128);
		downstairs 	= new Room(145);
		cellar 	 	= new Room(2);
		
		upOne 	= new Place(upstairs, 1);
		upTwo 	= new Place(upstairs, 2);
		downOne = new Place(downstairs, 1);
		downTwo = new Place(downstairs, 2);
		
		bob 	= new Person(120, "Bob", "Builder");
		pat 	= new Person(123, "Pat", "Postal");
		nev 	= new Person(432, "Neville", "Neg");
		bub 	= new Person(666, "Bob", "Elzebub");
		
		fun  	= new Group("Fun, fun fun");
		
		fun.addPerson(bob);
		fun.addPerson(pat);
		
		
	}

	/*
	 * constructors
	 */
	public void testPlace() {
		assertNotNull(upOne);
		assertNotNull(upTwo);
		assertNotSame(upOne, upTwo);
		assertEquals(upOne, upOne);
		assertEquals(upTwo, upTwo);
	}

	/*
	 * Test method for getID
	 */
	public void testGetID() {
		assertEquals(upOne.getPlaceID(), 1);
		assertEquals(upTwo.getPlaceID(), 2);
		assertTrue(upOne.getPlaceID() != 2);
	}

	/*
	 * history
	 */

	public void testPersonHistory(){
		
		try {
			upOne.getCurrent();
			assertTrue(false); //fail if no exception is thrown
		} catch (PersonNotFoundException e) {
			// This should happen
		}
		
		
		
		try {
			upOne.assign(bob);
			upTwo.assign(pat);
		} catch (ReservationConflictException e1) {
			fail();
		}
		
		try {
			assertEquals(bob, upOne.getCurrent());
			assertEquals(pat, upTwo.getCurrent());
			assertTrue(upOne.getCurrent() != pat);
			
			upOne.assign(pat);
			
			assertEquals(pat, upOne.getCurrent());
			assertTrue(upOne.getCurrent() != bob);
			assertEquals(upOne.getCurrent(), upTwo.getCurrent());
		}
		catch (PersonNotFoundException e) {
			// This should not happen
			fail("Could not find Person!");
		} catch (ReservationConflictException e) {
			// The Place is not reserved, should not happen
			fail("Reservation detected where none should be!");
		}
		
		
		List l = upOne.getHistory();
		Iterator it = l.iterator();
		
		assertEquals(it.next(), bob);
		assertEquals(it.next(), pat);
		assertTrue(!it.hasNext());
		
	}

	/*
	 * clearing the history
	 */
	public void testClearHistory() {
		testPersonHistory();
		
		try {
			upOne.getCurrent();
		} catch (PersonNotFoundException e1) {
			// This should not happen
			fail();
		}
		
		
		upOne.clearHistory();
		
		try {
			upOne.getCurrent();
			fail();
			
		} catch (PersonNotFoundException e) {
			// This should happen
		}
		
		
	}
	
	@Test
	public void testPreferrations() throws Exception {
		bob.setScore(20);
		pat.setScore(25);
		
		assertFalse(upOne.isPreferredBy());
		upOne.setPreferredBy(bob);
		assertTrue(upOne.isPreferredBy());
		assertEquals(bob, upOne.getPreferredBy());
		
		upOne.setPreferredBy(pat);
		assertEquals(pat, upOne.getPreferredBy());
		
		upOne.setPreferredBy(bob);
		assertEquals(pat, upOne.getPreferredBy());
	}

	/*
	 * Test of reservations
	 */
	public void testReservations() {
		assertTrue(upOne.isFree());
		
		upOne.reserve(fun);
		assertTrue(upOne.isReserved());
		assertFalse(upOne.isValidAndFree(nev));
		
		//can't assign when the reservation isn't met
		try {
			upOne.assign(nev);
			fail();
		} catch (ReservationConflictException e1) {
			// This should happen
		}
		
		assertTrue(upOne.isFree());
		assertTrue(upOne.isValidAndFree(bob));
		
		try {
			upOne.assign(bob);
		} catch (ReservationConflictException e1) {
			// bob is a part of the Reservation, this should not happen
			fail();
		}
		
		try {
			assertEquals(bob, upOne.getCurrent());
		} catch (PersonNotFoundException e) {
			// shouldn't happen
			fail();
		}
		
		upOne.clearHistory();
		assertTrue(upOne.isFree());
		assertTrue(upOne.isReserved());
		upOne.clearReservation();
		assertEquals(false, upOne.isReserved());
		try {
			//the Place is no longer reserved, Neville should get in
			upOne.assign(nev);
		} catch (ReservationConflictException e) {
			fail("Could not assign to non-reserved place");
		}
	}
	
	@Test
	public void testComparison() {		
		assertTrue(0 > upOne.compareTo(upTwo));
		assertTrue(0 < upTwo.compareTo(upOne));
		assertTrue(0 == upOne.compareTo(upOne));
		
		assertEquals(upOne, upOne);
		
		assertTrue(0 > upOne.compareTo(downOne));
		assertEquals(upOne.compareTo(downOne), upTwo.compareTo(downOne));
		assertEquals(upOne.compareTo(downOne), upTwo.compareTo(downTwo));
	}

	@Test
	public void testToString() {
		assertEquals(upOne.toString(), "128-1 (free space)");
		assertEquals(upTwo.toString(), "128-2 (free space)");
	}

}
